//2048游戏
using System;

namespace day05
{
    class Program
    {
        static void Main(string[] args)
        {
            //一维数组 二维数组 交错数组
            //2048 alg

            ini();
            
            show();
            move_left();
            show();
            move_right();
            show();
            move_bottom();
            show();
            move_top();
            show();
            move_top();
            show();
            move_left();
            show();
            move_left();
            show();
            Console.ReadKey();

        }

        static int[,] nuclear = new int[4, 4];
        static Random r = new Random();
        static void ini() {
            int ini_row = r.Next(0,4);
            int ini_col = r.Next(0, 4);
            nuclear[ini_row, ini_col] = 2;
            int temp0 = ini_row;
            int temp1 = ini_col;
            while ((temp0 == ini_row) && (temp1 == ini_col))
            {
                temp0 = r.Next(0, 4);
                temp1 = r.Next(0, 4);
            }
            nuclear[temp0, temp1] = 2;
            Console.WriteLine(ini_row.ToString()+ini_col.ToString()+temp0.ToString()+temp1.ToString());
        }
        static bool generate_at_random_coor() {
            int value = r.Next(0, 10) <= 8 ? 2 : 4;
            for (int i = 0; i < nuclear.GetLength(0); i++) {
                for (int j = 0; j < nuclear.GetLength(1); j++) {
                    if (nuclear[i,j] == 0) {
                        nuclear[i, j] = value;
                        return true;
                    }
                }
            }
            return false;
        }
        /// <summary>
        /// notice:direction->0,1,2,3
        /// 0:left 1:top 2:right 3:bottom
        /// </summary>
        /// <param name="direction"></param>
        /// <returns></returns>
        static bool judge_moveable(int direction) {
            bool judgement = false;

            if (direction == 0)
            { for (int i = 0; i < 4; i++) {
                    if (nuclear[i, 0] == 0) { judgement = true;
                        //Console.WriteLine("status:true");
                        break;
                    }
                    
                } }

            else if (direction == 1) {
                for (int i = 0; i < 4; i++)
                {
                    if (nuclear[0, i] == 0) { judgement = true;
                        break;
                    }
                    
                }
            }


            else if (direction == 2)
            {
                for (int i = 0; i < 4; i++)
                {
                    if (nuclear[i, 3] == 0) { judgement = true; 
                        break; }
                    
                }
            }


            else if (direction == 3) {
                for (int i = 0; i < 4; i++)
                {
                    if (nuclear[3, i] == 0) { judgement = true;
                        break;
                    }
                    
                }
            }
            else {

                Console.WriteLine("parameter error!");

            }

            return judgement;
        }
            
        
        /// <summary>
        /// 
        /// </summary>
        /// <returns>status: 0:succeed 1:not succeed 2:game over</returns>
        static int move_left() {
            int index = 0;
            bool jud = judge_moveable(0);
            if (judge_moveable(0))
            {
                for(int i = 0; i < 4; i++)
                {
                    index = 0;
                    if ((nuclear[i, 0] + nuclear[i, 1] + nuclear[i, 2] + nuclear[i, 3]) == 0) { continue; }
                    for (int j = 0; j < 5; j++) {
                        //去零
                        if (nuclear[i, index] == 0)
                        {
                            for (int k = index; k < 3; k++) { nuclear[i, k] = nuclear[i, k + 1]; }
                            nuclear[i, 3] = 0;
                            if (index > 0) index--;

                        }
                        else {
                            //合并相等项
                            if (nuclear[i, index] == nuclear[i, index + 1])
                            {
                                nuclear[i, index] *= 2;
                                for (int k = index + 1; k < 3; k++) { nuclear[i, k] = nuclear[i, k + 1]; }
                                nuclear[i, 3] = 0;
                                index++;
                            }
                            else {
                                index++;
                            }
                        }

                    }

                }
                generate_at_random_coor();
                if (judge_moveable(0) || judge_moveable(1) || judge_moveable(2) || judge_moveable(3)) { return 0; }
                else { return 2; }

            }
            else { return 1; }
            
        
        }
        static int move_top()
        {
            int index = 0;
            bool jud = judge_moveable(0);
            if (judge_moveable(0))
            {
                for (int i = 0; i < 4; i++)
                {
                    index = 0;
                    if ((nuclear[0, i] + nuclear[1, i] + nuclear[2, i] + nuclear[3, i]) == 0) { continue; }
                    for (int j = 0; j < 5; j++)
                    {
                        //去零
                        if (nuclear[index,i] == 0)
                        {
                            for (int k = index; k < 3; k++) { nuclear[ k,i] = nuclear[ k + 1,i]; }
                            nuclear[3,i] = 0;
                            if (index > 0) index--;

                        }
                        else
                        {
                            //合并相等项
                            if (nuclear[index,i] == nuclear[index + 1,i])
                            {
                                nuclear[index,i] *= 2;
                                for (int k = index + 1; k < 3; k++) { nuclear[k,i] = nuclear[k + 1,i]; }
                                nuclear[3,i] = 0;
                                index++;
                            }
                            else
                            {
                                index++;
                            }
                        }

                    }

                }
                generate_at_random_coor();
                if (judge_moveable(0) || judge_moveable(1) || judge_moveable(2) || judge_moveable(3)) { return 0; }
                else { return 2; }

            }
            else { return 1; }


        }

        static int move_right()
        {
            int index = 0;
            bool jud = judge_moveable(0);
            if (judge_moveable(0))
            {
                for (int i = 0; i < 4; i++)
                {
                    index = 3;
                    if ((nuclear[i, 0] + nuclear[i, 1] + nuclear[i, 2] + nuclear[i, 3]) == 0) { continue; }
                    for (int j = 0; j < 5; j++)
                    {
                        //去零
                        if (nuclear[i, index] == 0)
                        {
                            for (int k = index; k >0; k--) { nuclear[i, k] = nuclear[i, k - 1]; }
                            nuclear[i, 0] = 0;
                            if (index <3) index++;

                        }
                        else
                        {
                            //合并相等项
                            if (nuclear[i, index] == nuclear[i, index - 1])
                            {
                                nuclear[i, index] *= 2;
                                for (int k = index - 1; k >0; k--) { nuclear[i, k] = nuclear[i, k - 1]; }
                                nuclear[i, 0] = 0;
                                index--;
                            }
                            else
                            {
                                index--;
                            }
                        }

                    }

                }
                generate_at_random_coor();
                if (judge_moveable(0) || judge_moveable(1) || judge_moveable(2) || judge_moveable(3)) { return 0; }
                else { return 2; }

            }
            else { return 1; }


        }

        static int move_bottom()
        {
            int index = 0;
            bool jud = judge_moveable(0);
            if (judge_moveable(0))
            {
                for (int i = 0; i < 4; i++)
                {
                    index = 3;
                    if ((nuclear[0,i] + nuclear[1,i] + nuclear[2,i] + nuclear[3,i]) == 0) { continue; }
                    for (int j = 0; j < 5; j++)
                    {
                        //去零
                        if (nuclear[index,i] == 0)
                        {
                            for (int k = index; k > 0; k--) { nuclear[k,i] = nuclear[ k - 1,i]; }
                            nuclear[0,i] = 0;
                            if (index < 3) index++;

                        }
                        else
                        {
                            //合并相等项
                            if (nuclear[index,i] == nuclear[index - 1,i])
                            {
                                nuclear[index,i] *= 2;
                                for (int k = index - 1; k > 0; k--) { nuclear[k,i] = nuclear[k - 1,i]; }
                                nuclear[0,i] = 0;
                                index--;
                            }
                            else
                            {
                                index--;
                            }
                        }

                    }

                }
                generate_at_random_coor();
                if (judge_moveable(0) || judge_moveable(1) || judge_moveable(2) || judge_moveable(3)) { return 0; }
                else { return 2; }

            }
            else { return 1; }


        }

        static void show() {
            for (int i = 0; i < 4; i++) {

                string st = string.Format("{0}\t{1}\t{2}\t{3}", nuclear[i, 0], nuclear[i, 1], nuclear[i, 2], nuclear[i, 3]);
                    Console.WriteLine(st);
                
            }
            Console.WriteLine();
            Console.WriteLine();
        }



    }
}
